#!/usr/bin/python
# -*- coding: utf-8 -*-
# File: customview.py
# Author: Tomás Vírseda
# License: GPL v3
# Description: a customview widget. Available customviews:
#   - IconView: completed
#   - ListView: #FIXME: almost finished.
#   - WidgetView: #FIXME: Thinking in it.

import os
import re
import urllib
import datetime
import gtk

from rdflib import Literal

from vazaarlib.utils import fuzzy_date
from vazaarlib.namespaces import *
from vazaarlib.ui.widgets.genericlistview import GenericListView
from vazaarlib.ui.dialogs import AreYouSure
from vazaarlib.constants import VAZAAR_USER_RESOURCES_DIR
from vazaarlib.constants import _

class ListView(gtk.ScrolledWindow):
    def __init__(self, gui, columns, resources):
        gtk.ScrolledWindow.__init__(self)
        self.gui = gui
        self.listview = GenericListView(columns)
        self.popup = self.create_resources_popup()

        for resource in resources:
            id = resource[0]
            if type(resource[1]) == Literal:
                icon = self.gui.icons.get_icon_by_mime(resource[1], 48, 48)
            else:
                icon = resource[1]
            date = resource[2]
            title = resource[3]
            self.listview.add((id, icon, date, title))

        self.listview.connect('row-activated', self.item_activated)
        self.listview.connect('button-press-event', self.popup_menu)

        self.add(self.listview)
        self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.set_shadow_type(gtk.SHADOW_IN)
        self.show_all()

    def item_activated(self, listview, path, view_column, *user_data):
        selection = listview.get_selection()
        model, selected = selection.get_selected_rows()
        path = selected[0]
        iter = model.get_iter_from_string(str(path[0]))
        id = model.get_value(iter, 0)
        self.gui.actions.display_resource(id)

        """
        # FIXME: it only displays the last selected resource not all of them
        for path in selected:
            iter = model.get_iter_from_string(str(path[0]))
            id = model.get_value(iter, 0)
            self.gui.actions.display_resource(id)
        """

    def popup_menu(self, treeview, event):
        if event.button == 3:
            x = int(event.x)
            y = int(event.y)
            time = event.time
            pthinfo = treeview.get_path_at_pos(x, y)
            if pthinfo is not None:
                path, col, cellx, celly = pthinfo
                treeview.grab_focus()
                treeview.set_cursor( path, col, 0)
                self.popup.popup( None, None, None, event.button, time)
            return 1

    def create_resources_popup(self):
        menu = gtk.Menu()
        title = gtk.ImageMenuItem('<b>Operations</b>')
        menu.append(title)
        menu.show_all()

        return menu


class IconView(gtk.ScrolledWindow):
    def __init__(self, gui, columns, resources):
        t1 = datetime.datetime.now()
        gtk.ScrolledWindow.__init__(self)
        self.gui = gui
        self.resources = resources
        self.vstore = self.gui.app.vstore
        self.model = gtk.ListStore(
                                    str,            # Identifier
                                    gtk.gdk.Pixbuf, # icon
                                    str,            # title
                                    str             # date added
                                )
        self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.set_shadow_type(gtk.SHADOW_IN)
        self.view = gtk.IconView()
        self.view.set_model(self.model)
        self.view.set_orientation(gtk.ORIENTATION_HORIZONTAL)
        self.view.set_selection_mode(gtk.SELECTION_MULTIPLE)
        self.view.set_reorderable(True)
        self.view.connect('item-activated', self.item_activated)
        self.view.connect('button-press-event', self.popup_menu)
        self.view.set_item_width(400)
        self.view.set_spacing(10)
        self.view.set_pixbuf_column(1)
        #self.view.set_text_column(2)
        self.view.set_markup_column(3)
        self.populate()
        self.popup = self.create_resources_popup()
        self.add(self.view)
        self.view.show_all()
        self.show_all()
        t2 = datetime.datetime.now()
        delta = t2 - t1
        #print "updating customview took: %s" % delta

    def link_to_collection(self, widget, *args):
        self.gui.colview.update_selected_collections()
        collections = self.gui.frontend['target-col']
        resources = self.gui.frontend['target-res']

        if not collections or not resources:
            return

        self.gui.app.vstore.link_resources_to_collections(collections, resources)

        head = 'Resources linked to Collections:\n'
        body = ''
        for col in collections:
            col_name = self.gui.ask.get_property(col, NIE['title'])
            head += '·' + col_name + '\n'
        for res in resources:
            title = self.gui.ask.get_property(res, NIE['title'])
            body += '+ ' + title + '\n'
        icon = self.gui.icons.get_icon_by_name('linked.svg', 128, 128)
        self.gui.actions.notify(head, body, icon)


    def edit_resource(self, widget, *args):
        paths = self.view.get_selected_items()
        model = self.view.get_model()
        target_list = []
        for path in paths:
            iter = model.get_iter_from_string(str(path[0]))
            id = model.get_value(iter, 0)
            target_list.append(id)
        try:
            self.gui.editor.update_id(target_list[0])
        except:
            pass
        self.gui.editor.show_dialog()

    def open_resource(self, widget, *args):
        paths = self.view.get_selected_items()
        model = self.view.get_model()
        target_list = []
        for path in paths:
            iter = model.get_iter_from_string(str(path[0]))
            id = model.get_value(iter, 0)
            target_list.append(id)

        for id in target_list:
            fileurl = self.gui.ask.get_property(id, NFO['fileUrl'])
            try:
                command = '/usr/bin/xdg-open %s' % re.escape(fileurl)
                os.system(command)
            except: pass

            try:
                command = '/usr/bin/xdg-open %s' % (VAZAAR_USER_RESOURCES_DIR + '/' + fileurl)
                os.system(command)
            except: pass

            try:
                command = '/usr/bin/xdg-open %s' % fileurl
                os.system(command)
            except: pass

        self.gui.actions.update_gui()


    def delete_selected(self, widget, *args):
        ays = AreYouSure()
        dialog = ays.get_dialog()
        dialog.output = dialog.run()
        if dialog.output == 0:
            paths = self.view.get_selected_items()
            model = self.view.get_model()
            target_list = []
            deleted = '--\n'
            for path in paths:
                iter = model.get_iter_from_string(str(path[0]))
                id = model.get_value(iter, 0)
                title = model.get_value(iter, 3)
                deleted += urllib.unquote(title) + '\n--\n'
                target_list.append(id)
                self.gui.actions.delete_data_resource(id)
            self.gui.app.vstore.delete_resources(target_list)
            icon = self.gui.icons.get_icon_by_name('Trash.svg', 128, 128)
            self.gui.actions.notify("Resource(s) deleted", deleted, icon)
            self.gui.actions.update_gui()
            self.gui.statusbar.set_text("<b>Selected resources deleted</b>")

        else:
            self.gui.statusbar.set_text("<b>Operation canceled</b>")
        dialog.destroy()

    def create_resources_popup(self):
        menu = gtk.Menu()
        try:
            # Edit resource properties
            mnuitem = gtk.ImageMenuItem('Edit properties')
            mnuitem.connect('activate', self.edit_resource)#, '          add_to_collection     ')
            icon = self.gui.widget.render_icon(gtk.STOCK_EDIT, gtk.ICON_SIZE_BUTTON)
            mnuitem.set_image(gtk.image_new_from_pixbuf(icon))
            menu.append(mnuitem)

            # Open resource with default application
            mnuitem = gtk.ImageMenuItem('Open this resource')
            mnuitem.connect('activate', self.open_resource)#, '          add_to_collection     ')
            icon = self.gui.widget.render_icon(gtk.STOCK_EXECUTE, gtk.ICON_SIZE_BUTTON)
            mnuitem.set_image(gtk.image_new_from_pixbuf(icon))
            menu.append(mnuitem)

            # Delete selected resources
            mnuitem = gtk.ImageMenuItem('Delete selected resource(s)')
            mnuitem.connect('activate', self.delete_selected)
            icon = self.gui.widget.render_icon(gtk.STOCK_DELETE, gtk.ICON_SIZE_BUTTON)
            mnuitem.set_image(gtk.image_new_from_pixbuf(icon))
            menu.append(mnuitem)

            # Separator
            mnuitem = gtk.SeparatorMenuItem()
            menu.append(mnuitem)

            # Link to Collection
            mnuitem = gtk.ImageMenuItem('Link to collection(s)')
            mnuitem.connect('activate', self.link_to_collection)
            icon = self.gui.icons.get_icon_by_name('linked.svg', 24, 24)
            mnuitem.set_image(gtk.image_new_from_pixbuf(icon))
            menu.append(mnuitem)

            menu.show_all()
            return menu

        except Exception, error:
            print "cv.create_resources_popup", error

    def get_target(self, iconview, paths, user_data):
        model = iconview.get_model()
        for path in paths:
            iter = model.get_iter_from_string(str(path))
            id = model.get_value(iter, 0)
            # Add to source target list
            self.gui.frontend['target-res'].append(id)

    def popup_menu(self, iconview, event):
        if event.button == 3:
            self.gui.frontend['target-res'] = []
            # update target
            iconview.selected_foreach(self.get_target)
            x = int(event.x)
            y = int(event.y)
            time = event.time
            pthinfo = iconview.get_path_at_pos(x, y)
            if pthinfo is not None:
                path = pthinfo
                self.popup = self.create_resources_popup()
                iconview.grab_focus()
                iconview.set_cursor(path, None, False)
                # clone popup and add options to unlink from collections

                linkedcols = self.get_linked_collections(path[0])
                id = self.get_id_from_path(str(path[0]))
                for col in linkedcols:
                    mnuitem = self.get_unlink_from_collection_menuitem(col, id)
                    self.popup.append(mnuitem)
                self.popup.show_all()
                self.popup.popup( None, None, None, event.button, time)
            return 1

    def get_id_from_path(self, path):
        model = self.view.get_model()
        iter = model.get_iter_from_string(path)
        id = model.get_value(iter, 0)

        return id

    def get_unlink_from_collection_menuitem(self, col, id):
        title = self.gui.ask.get_property(col, NIE['title'])
        mnuitem = gtk.ImageMenuItem('Unlink from collection: %s' % title)
        mnuitem.connect('activate', self.unlink_from_collection, col, id)
        icon = self.gui.icons.get_icon_by_name('unlinked.svg', 24, 24)
        mnuitem.set_image(gtk.image_new_from_pixbuf(icon))

        return mnuitem



    def get_linked_collections(self, path):
        model = self.view.get_model()
        iter = model.get_iter_from_string(str(path))
        id = model.get_value(iter, 0)
        result = self.gui.ask.collections_linked_to_resource(id)

        return result


    def unlink_from_collection(self, widget, col, id):
        col_name = self.gui.ask.get_property(col, NIE['title'])
        unlinked = '\n'
        for id in self.gui.frontend['target-res']:
            self.gui.app.vstore.unlink_resource_from_collection(col, id)
            title = self.gui.ask.get_property(id, NIE['title'])
            unlinked += '- %s\n' % title
        icon = self.gui.icons.get_icon_by_name('unlinked.svg', 128, 128)
        self.gui.actions.notify('Resource(s) unlinked from collection %s' % col_name, unlinked, icon)
        self.gui.actions.update_gui()


    def populate(self):
        for resource in self.resources:
            try:
                id = resource[0]
                media = self.gui.ask.get_property(id, NIE['mimeMedia'])
                subtype = self.gui.ask.get_property(id, NIE['mimeSubtype'])
                if media in ('image', 'application', 'text'):
                    if subtype != 'html':
                        url = str(self.gui.ask.get_property(id, NFO['fileUrl']))
                        uri = '\'' + urllib.quote(url) + '\''
                        icon_path = self.gui.icons.thumbnail_path_from_uri(uri)
                        #print icon_path
                        icon = self.gui.icons.get_icon_from_path(url, icon_path, 96)
                        #print icon
                    else:
                        icon = None

                    if icon is None:
                        # Get default icon
                        if type(resource[1]) == Literal:
                            icon = self.gui.icons.get_icon_by_mime(resource[1], 96, 96)
                        else:
                            icon = resource[1]
                else:
                    if type(resource[1]) == Literal:
                        icon = self.gui.icons.get_icon_by_mime(resource[1], 96, 96)
                    else:
                        icon = resource[1]
                date = resource[2]
                text = resource[3]
                self.model.append((id, icon, date, text))
            except Exception, error:
                #print error
                id = resource[0]
                icon = self.gui.icons.get_icon_by_name(PIMO['Collection'], 96, 96)
                #icon = self.gui.widget.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_BUTTON)
                date = resource[2]
                text = resource[3]
                self.model.append((id, icon, date, text))


    def item_activated(self, iconview, path, *user_data):
        try:
            selected = iconview.get_selected_items()
            path = str(selected[0][0])
            model = iconview.get_model()
            iter = model.get_iter_from_string(path)
            id = model.get_value(iter, 0)
            self.gui.editor.update_id(id)
            self.gui.actions.display_resource(id)
            self.gui.frontend['notebook'].set_show_tabs(True)
            #self.gui.ask.describe(id)
        except:
            pass

